using System.Linq;
using TMPro;
using UnityEngine;

public class UI_SkillTree : MonoBehaviour,ISaveable
{
    [SerializeField] private int skillPoints = 20;
    [SerializeField] private TextMeshProUGUI skillPointText;
    [SerializeField] private UI_TreeConnectionHandler[] handlers;
    [SerializeField] private UI_TreeNode[] skillNodes; 
    public PlayerSkillManager playerSkillManager { get; private set; }
    public void Start()
    {
        UpdateAllHandler();
    }

    private void GetNeededComponent()
    {
        playerSkillManager = FindAnyObjectByType<PlayerSkillManager>();
        skillNodes = GetComponentsInChildren<UI_TreeNode>(true);
    }
    public void UpdateAllDefaultSkillUnlock()
    {
        GetNeededComponent();

        foreach (var node in skillNodes)
            node.SetTreeNode();

    }

    [ContextMenu("Update All Connectios")]
    public void UpdateAllHandler()
    {
        foreach (var handler in handlers)
            handler.UpdateAllConnection();
    }

    [ContextMenu("Reset Skill Tree")]
    public void RefundAllSkill()
    {
        UI_TreeNode[] nodes = GetComponentsInChildren<UI_TreeNode>();
        foreach (var node in nodes)
            node.Refund();
    }
    public bool EnoughSkillPoints(int cost) => skillPoints >= cost;
    public void AddSkillPoints(int points)
    {
        skillPoints += points;
        skillPointText.text = skillPoints.ToString();
    }
    public void RemoveSkillPoints(int cost)
    {
        skillPoints -= cost;
        skillPointText.text = skillPoints.ToString();
    }

    public void SaveData(ref GameData gameData)
    {
        gameData.skillPoints = skillPoints;

        gameData.skillNodes.Clear();
        foreach (var node in skillNodes)
        {
            if (node == null)
                continue;

            gameData.skillNodes[node.skillData.displayName] = node.isUnlocked;
        }

        gameData.skillUpgrade.Clear();
        foreach (var skill in playerSkillManager.skills)
        {
            if (skill == null)
                continue;

            gameData.skillUpgrade[skill.GetSkillType()] = skill.GetSkillUpgradeType();
        }
    }

    public void LoadData(GameData gameData)
    {
        skillPoints = gameData.skillPoints;
        skillPointText.text = skillPoints.ToString();
        
        foreach (var node in skillNodes)
        {
            if (node == null)
                continue;

            if (gameData.skillNodes.TryGetValue(node.skillData.displayName, out bool isUnlocked) && isUnlocked)
                node.UnlockInLoadData();
        }

        foreach (var skill in playerSkillManager.skills)
        {
            if (gameData.skillUpgrade.TryGetValue(skill.GetSkillType(), out SkillUpgradeType skillUpgradeType))
            {
                UI_TreeNode skillNode = skillNodes.FirstOrDefault(target => target.skillData.skillUpgradeData.skillUpgradeType == skillUpgradeType);

                if (skillNode != null)
                    skill.SetSkillUpgrade(skillNode.skillData);
            }
        }
    }
}
